package com.poker.duiued;

import android.annotation.SuppressLint;
import android.app.AlertDialog;;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.*;
import android.text.TextUtils;
import android.util.Log;
import android.view.*;
import android.widget.*;
import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.JsonArray;
import com.poker.iuious.yhyhjs.ChatAdapter;
import com.poker.iuious.yhyhjs.jklimj.ChatBean;
import com.poker.iuious.yhyhjs.jklimj.User;
import com.poker.jkiuus.R;
import com.poker.jkiuus.uyrfgd.AppManager;
import com.poker.jkiuus.uyrfgd.DatabaseHelper;
import com.poker.jkiuus.uyrfgd.FlagHolder;
import okhttp3.*;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AiActivity extends AppCompatActivity {

    public ListView listView;
    public EditText et_send_msg;
    public Button btn_send;
    public ChatAdapter adapter;
    private ImageView settingsImageView;
    private TextView tv_login_status;
    private Toast currentToast;

    private List<ChatBean> chatBeanList;
    private String welcome[];
    private String sendMsg;
    private ChatBean chatBean;
    private int MSG_OK = 1;
    private long exitTime = 0;
    private int position;
    private DatabaseHelper databaseHelper;
    private String userName;
    private User user = new User();

    private static final String WEB_SITE = "https://api.ownthink.com/bot";
    private static final String KEY = "d4c4e406e582ebd2488e1aa0055d76e0";
    private static final String APPID = "GAI2dN31";
    private static final String Url = "https://api.chatkore.com/v1/chat/completions";
    private static final String CONTENT_TYPE = "application/json";
    private static final String AUTHORIZATION = "Bearer sk-p5ir9HefTt0lPlH8dVGtnZBDugcewfGtYWma9RXSRlD3u7dB";

    private static final String PREFS_NAME = "AiActivityPrefs";
    private static final String PREFS_COUNT_FREE = "countFree";
    private static final String PREFS_COUNT_LOGIN = "countLogin";
    private static final String PREFS_DATE = "date";

    @SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ai);
        AppManager.addActivity(this);
        databaseHelper = new DatabaseHelper(this);
        tv_login_status = findViewById(R.id.tv_login_status);


        if(getIntent().hasExtra("USER_NAME")){
            userName = getIntent().getStringExtra("USER_NAME");
            tv_login_status.setText("User： "+userName);
        }else {
            userName = "";
        }

        user = databaseHelper.queryUserByNameOrEmail(userName);

        if (userName.equals("")){
            showComparisonDialog();
        }

        initView();

    }


    public void initView() {
        listView = (ListView) findViewById(R.id.list);
        et_send_msg = (EditText) findViewById(R.id.et_send_msg);
        btn_send = (Button) findViewById(R.id.btn_send);
        welcome = getResources().getStringArray(R.array.welcome);
        settingsImageView = findViewById(R.id.iv_settings);
        if (user != null){
            chatBeanList = databaseHelper.getChatHistory(String.valueOf(user.getId()));
        }
        if (chatBeanList == null){
            chatBeanList = new ArrayList<>();
        }
        adapter = new ChatAdapter(this, chatBeanList);
        listView.setAdapter(adapter);
        btn_send.setOnClickListener(v -> sendData());
        et_send_msg.setOnKeyListener((v, keyCode, keyEvent) -> {
            if ((keyCode == KeyEvent.KEYCODE_ENTER) && (keyEvent.getAction() == KeyEvent.ACTION_DOWN)) {
                sendData();
            }
            return false;
        });
        settingsImageView.setOnClickListener(v -> {

            Intent intent = new Intent(AiActivity.this, SettingsActivity.class);
            intent.putExtra("USER_NAME",userName);
            startActivity(intent);
            overridePendingTransition(R.anim.zoom_in, R.anim.zoom_out);
        });

        tv_login_status.setOnClickListener(v -> {
            if ("".equals(userName)){
                Intent intent = new Intent(AiActivity.this, LoginActivity.class);
                startActivity(intent);
                overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
            }else {
                showPopupMenu(v);
            }
        });

        if (chatBeanList.isEmpty()) {
            showFirstMessage();
        }

    }

    private void showFirstMessage() {
        position = (int) (Math.random() * welcome.length);
        showData(welcome[position]);

        if (user != null) {
            databaseHelper.saveChatHistory(String.valueOf(user.getId()),welcome[position],ChatBean.RECEIVE);
        }
    }


    private void showData(String message) {
        ChatBean chatBean = new ChatBean();
        chatBean.setMessage(message);
        chatBean.setState(ChatBean.RECEIVE);
        chatBeanList.add(chatBean);
        adapter.notifyDataSetChanged();
    }

    private void sendData() {
        sendMsg = et_send_msg.getText().toString();
        if (TextUtils.isEmpty(sendMsg)) {
            if (currentToast!=null){
                currentToast.cancel();
            }

            currentToast = Toast.makeText(this, "You haven't entered any information yet!", Toast.LENGTH_SHORT);
            currentToast.show();

            return;
        }

        if (!btn_send.isEnabled()) {
            showCenteredToast("Please try again later!");
            return;
        }

        btn_send.setEnabled(false);
        btn_send.setBackgroundResource(R.drawable.rounded_button2);
        et_send_msg.setText("");

        chatBean = new ChatBean();
        chatBean.setMessage(sendMsg);
        chatBean.setState(ChatBean.SEND);
        chatBeanList.add(chatBean);
        adapter.notifyDataSetChanged();
        if (user != null){
            databaseHelper.saveChatHistory(String.valueOf(user.getId()), sendMsg, ChatBean.SEND);
            databaseHelper.insertUserQuery(user.getId(), sendMsg, getCurrentDate());
        }

        boolean isLoginUser = databaseHelper.queryUserByName(userName);
        checkAndUpdateCount(isLoginUser);
    }

    private void getDataFromServerForFree() {
        OkHttpClient okHttpClient = new OkHttpClient();

        try {
            String encodeMsg = URLEncoder.encode(sendMsg, "UTF-8");
            Request request = new Request.Builder()
                    .url(WEB_SITE + "?key=" + KEY + "&appid=" + APPID + "&spoken=" + encodeMsg)
                    .build();
            Call call = okHttpClient.newCall(request);

            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    System.out.println(e);
                    handler.post(()->{
                        btn_send.setEnabled(true);
                        btn_send.setBackgroundResource(R.drawable.rounded_button);
                        showCenteredToast("Master, I have a fault, please try again later!");
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String res = response.body().string();
                    Message msg = new Message();
                    msg.what = MSG_OK;
                    msg.obj = res;
                    handler.sendMessage(msg);
                }
            });
        } catch (Exception e) {
            handler.post(()->{
                btn_send.setEnabled(true);
                btn_send.setBackgroundResource(R.drawable.rounded_button);
                showCenteredToast("Master, I have a fault, please try again later!");
            });
            e.printStackTrace();
        }
    }

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void dispatchMessage(@NonNull Message msg) {
            super.dispatchMessage(msg);
            if (msg.what == 1) {
                if (msg.obj != null) {
                    String result = (String) msg.obj;
                    Log.i("handler", result);
                    paresData(result);
                }
            }
        }
    };

    private void paresData(String content) {
        try {
            JSONObject jsonObject = new JSONObject(content);
            JSONObject data = jsonObject.getJSONObject("data");
            String resContent = data.getJSONObject("info").getString("text");
            resContent = resContent.replace("{br}","\n");
            int code = data.getInt("type");
            Log.i("paresData", resContent + "," + code);
            updateView(code, resContent);
            btn_send.setEnabled(true);
            btn_send.setBackgroundResource(R.drawable.rounded_button);
            if (user != null){
                databaseHelper.saveChatHistory(String.valueOf(user.getId()),resContent,ChatBean.RECEIVE);
            }
        } catch (JSONException e) {
            handler.post(()->{
                btn_send.setEnabled(true);
                btn_send.setBackgroundResource(R.drawable.rounded_button);
                showCenteredToast("Master, I have a fault, please try again later!");
            });
            e.printStackTrace();
        }
    }

    private void updateView(int code, String content) {
        switch (code) {
            case 4094:
                showData("Master, I'm tired today, I'm going to rest, come and play with me tomorrow.");
                break;
            case 40005:
                showData("Master, are you speaking Martian?");
                break;
            case 40886:
                showData("Master, I'm going on a date today, and we'll talk another day.");
                break;
            case 40807:
                showData("Master, I'll play with you tomorrow, whine...");
                break;
            case 102:
                showData("Master, I'm launching a new version soon, please wait a minute!");
                break;
            default:
                showData(content);
                break;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                if (currentToast!=null){
                    currentToast.cancel();
                }

                currentToast = Toast.makeText(AiActivity.this, "Press again to exit the program!", Toast.LENGTH_SHORT);
                currentToast.show();

                exitTime = System.currentTimeMillis();
            } else {
                AiActivity.this.finish();
                System.exit(0);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);

    }

    private void getDataFromServerForLoginUser(){
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Handler handler = new Handler(Looper.getMainLooper());

        try {
            sendMsg = URLEncoder.encode(sendMsg, "utf-8");
        } catch (UnsupportedEncodingException e) {
            handler.post(()->{
                btn_send.setEnabled(true);
                btn_send.setBackgroundResource(R.drawable.rounded_button);
                showCenteredToast("Master, I have a fault, please try again later!");
            });
            e.printStackTrace();
        }

        executor.execute(() -> {
            OkHttpClient client = new OkHttpClient();
            MediaType mediaType = MediaType.parse(CONTENT_TYPE);
            RequestBody body = RequestBody.create(mediaType, "{\n\"model\": \"gpt-3.5-turbo\",\n\"messages\": [{\"role\": \"user\", \"content\": \""+sendMsg+"\"}],\n\"temperature\": 0.7\n}");
            Request request = new Request.Builder()
                    .url(Url)
                    .post(body)
                    .addHeader("Content-Type", CONTENT_TYPE)
                    .addHeader("Authorization", AUTHORIZATION)
                    .build();

            try {
                Response response = client.newCall(request).execute();
                String responseBody = response.body().string();
                Log.i("responseBody",responseBody);

                handler.post(() -> {
                    try {
                        JSONObject jsonObject = new JSONObject(responseBody);
                        Log.i("jsonObject",jsonObject.toString());
                        JSONArray choicesArray = jsonObject.getJSONArray("choices");
                        for (int i = 0; i < choicesArray.length(); i++) {
                            JSONObject choice = choicesArray.getJSONObject(i);
                            JSONObject messageObject = choice.getJSONObject("message");
                            String content = messageObject.getString("content");
                            Log.i("content", content);
                            updateView(1, content);
                            btn_send.setEnabled(true);
                            btn_send.setBackgroundResource(R.drawable.rounded_button);
                            if (user != null){
                                databaseHelper.saveChatHistory(String.valueOf(user.getId()),content,ChatBean.RECEIVE);
                            }
                        }
                    } catch (JSONException e) {
                        handler.post(()->{
                            btn_send.setEnabled(true);
                            btn_send.setBackgroundResource(R.drawable.rounded_button);
                            showCenteredToast("Master, I have a fault, please try again later!");
                        });
                        e.printStackTrace();
                    }
                });

                if (!response.isSuccessful()){
                    handler.post(()->{
                        btn_send.setEnabled(true);
                        btn_send.setBackgroundResource(R.drawable.rounded_button);
                        showData("Master, I have a fault, please try again later!");
                    });
                    throw new IOException("Unexpected code " + response);
                }
            } catch (IOException e) {
                handler.post(()->{
                    btn_send.setEnabled(true);
                    btn_send.setBackgroundResource(R.drawable.rounded_button);
                    showCenteredToast("Master, I have a fault, please try again later!");
                });
                e.printStackTrace();
            }
        });
    }

    private void checkAndUpdateCount(boolean isLoginUser) {
        SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        String savedDate = prefs.getString(PREFS_DATE, "");
        String currentDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());

        int countFree = prefs.getInt(PREFS_COUNT_FREE, 0);
        int countLogin = prefs.getInt(PREFS_COUNT_LOGIN, 0);

        if (!currentDate.equals(savedDate)) {

            countFree = 0;
            countLogin = 0;
            prefs.edit().putString(PREFS_DATE, currentDate).apply();
        }

        if (isLoginUser) {
            if (countLogin >= 50) {

                showLimitReachedDialog(true);
                return;
            }
            prefs.edit().putInt(PREFS_COUNT_LOGIN, countLogin + 1).apply();
            getDataFromServerForLoginUser();
        } else {
            if (countFree >= 10) {

                showLimitReachedDialog(false);
                return;
            }
            prefs.edit().putInt(PREFS_COUNT_FREE, countFree + 1).apply();
            getDataFromServerForFree();
        }
    }

    private void showLimitReachedDialog(boolean isRegisteredUser) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Limit Reached");

        if (isRegisteredUser) {
            builder.setMessage("You have reached your daily limit of 50 requests. Please try again tomorrow!");
        } else {
            builder.setMessage("You have reached your daily limit of 10 requests. Please register to continue using the service.");
        }

        builder.setPositiveButton("OK", (dialog, which) -> dialog.dismiss());


        if (!isRegisteredUser) {
            builder.setNegativeButton("Register", (dialog, which) -> {

                Intent intent = new Intent(this,RegisterActivity.class);
                startActivity(intent);
            });
        }

        AlertDialog dialog = builder.create();
        dialog.show();
    }

    private void showComparisonDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        LayoutInflater inflater = this.getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.dialog_robot_comparison, null);
        builder.setView(dialogView);

        builder.setPositiveButton("Close", (dialog, id) -> dialog.dismiss());
        builder.setCancelable(false);

        AlertDialog dialog = builder.create();
        dialog.show();
    }

    private void showPopupMenu(View anchor) {
        PopupMenu popupMenu = new PopupMenu(this, anchor);
        popupMenu.getMenu().add("Switch users");
        popupMenu.setOnMenuItemClickListener(item -> {

            if (item.getTitle().equals("Switch users")) {

                Intent intent = new Intent(AiActivity.this, LoginActivity.class);
                startActivity(intent);
                overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
                finish();
            }
            return true;
        });
        popupMenu.show();
    }

    private String getCurrentDate() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        return dateFormat.format(new Date());
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (FlagHolder.isFlag()) {
            refreshChatHistory();
            if (chatBeanList.isEmpty()) {
                showFirstMessage();
            }
            FlagHolder.setFlag(false);
        }
    }

    private void refreshChatHistory() {

        if (user != null) {
            chatBeanList.clear();
            chatBeanList.addAll(databaseHelper.getChatHistory(String.valueOf(user.getId())));
            adapter.notifyDataSetChanged();
        }
    }

    private void showCenteredToast(String message) {
        if (currentToast != null) {
            currentToast.cancel();
        }

        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.custom_toast,
                findViewById(R.id.custom_toast_container));

        TextView text = layout.findViewById(R.id.text);
        text.setText(message);

        currentToast = new Toast(getApplicationContext());
        currentToast.setGravity(Gravity.CENTER, 0, 0);
        currentToast.setDuration(Toast.LENGTH_SHORT);
        currentToast.setView(layout);
        currentToast.show();
    }


}